﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace PddHelper.Framework
{
    /// <summary>
    /// 实体类拷贝扩展类
    /// </summary>
    public static class ModelCopyHelper
    {
        /// <summary>
        /// 对象拷贝,单层类使用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <param name="source">源数据对象</param>
        /// <param name="target">赋值目标对象</param>
        /// <param name="IgnoreColumns">排除忽略列</param>
        public static void CopyTo<T, K>(this T source, K target, List<string> IgnoreColumns = null) where T : class, new() where K : class, new()
        {
            var _ignoreColumns = (IgnoreColumns == null) ? new List<string>() : IgnoreColumns.Select(ex => ex.ToLower()).ToList();//全转小写

            PropertyInfo[] source_ps = DynamicMethod<T>.Instance.PropertyInfos;//源数据
            PropertyInfo[] target_ps = DynamicMethod<K>.Instance.PropertyInfos;//目标数据 

            foreach (var item in target_ps)
            {
                if (!_ignoreColumns.Contains(item.Name.ToLower()))//忽略属性
                {
                    var value = source.GetValue(item.Name);
                    target.SetValue(item.Name, value);
                }
            }
        }

        /// <summary>
        /// 集合拷贝,单层类使用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <param name="source">源数据对象</param>
        /// <param name="target">赋值目标对象</param>
        /// <param name="IgnoreColumns">排除忽略列</param>
        public static void CopyTo<T, K>(this List<T> source, List<K> target, List<string> IgnoreColumns) where T : class, new() where K : class, new()
        {
            if (source != null && target != null)
            {
                foreach (var item in source)
                {
                    var obj = new K();
                    CopyTo(item, obj, IgnoreColumns);
                    target.Add(obj);
                }
            }
        }

        /// <summary>
        /// 对象深拷贝ByJson,多层类使用
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <param name="source">源数据对象</param>
        public static K DepthCopyTo<K>(this object source) 
        {
            var str = JsonConvert.SerializeObject(source);
            var obj = JsonConvert.DeserializeObject<K>(str);
            return obj;
        }

        /// <summary>
        /// 实体获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object GetValue<T>(this T source, string name) where T : class, new()
        {
            var obj = DynamicMethod<T>.Instance.GetValue(source, name);
            return obj;
        }

        /// <summary>
        /// 实体设置赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static void SetValue<T>(this T source, string name, object value) where T : class, new()
        {
            DynamicMethod<T>.Instance.SetValue(source, name, value);
        }
    }
}
